/**********************************************************************
 *** *                                                            * ***
 *** *  Copyright (c) 2013 Harmonia Holdings Group LLC            * ***
 *** *                                                            * ***
 *** * Permission is hereby granted to use, modify, copy, and     * ***
 *** * distribute this software and its documentation for any     * ***
 *** * purpose only without profit, provided that the above       * ***
 *** * Copyright Notice appears in all copies and that both the   * ***
 *** * Copyright Notice and this Permission Notice appears in     * ***
 *** * every copy of supporting documentation.  No title to nor   * ***
 *** * ownership of the software is transferred hereby.  The name * ***
 *** * of Harmonia Holdings Group LLC shall not be used in        * ***
 *** * advertising or publicity related to the distribution of    * ***
 *** * the software without specific, written, prior permission.  * ***
 *** * This software is provided as-delivered without expressed   * ***
 *** * or implied warranty.  Harmonia Holdings Group LLC          * ***
 *** * makes no representation about the suitability of this      * ***
 *** * software for any purpose and accepts no responsibility for * ***
 *** * its use.                                                   * ***
 *** *                                                            * ***
 *** ************************************************************** ***
 *** *                                                            * ***
 *** * This program is free software; you can redistribute it     * ***
 *** * and/or modify it under the terms of the GNU General Public * ***
 *** * License as published by the Free Software Foundation;      * ***
 *** * either version 2 of the License, or (at your option) any   * ***
 *** * later version.                                             * ***
 *** *                                                            * ***
 *** * This program is distributed in the hope that it will be    * ***
 *** * useful, but WITHOUT ANY WARRANTY; without even the implied * ***
 *** * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR    * ***
 *** * PURPOSE.  See the GNU General Public License for more      * ***
 *** * details.                                                   * ***
 *** *                                                            * ***
 *** * You should have received a copy of the GNU General Public  * ***
 *** * License along with this program; if not, write to the Free * ***
 *** * Software Foundation, Inc., 51 Franklin Street, Fifth       * ***
 *** * Floor, Boston, MA 02110-1301, USA.                         * ***
 *** *                                                            * ***
 *** * For more information: http://www.gnu.org/licenses/gpl.html * ***
 *** *                                                            * ***
 **********************************************************************/
package org.etexascode.interrep.datamodel;
import java.io.Serializable;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import org.apache.commons.lang3.builder.HashCodeBuilder;

/**
 * Detector event model.
 * @author unknown
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class DetectorEvent implements Serializable {
	/** Serial ID. */
	@XmlTransient
	private static final long serialVersionUID = 3045420162460601805L;


	/** The detector ID. */
	@XmlElement
	int detectorId = 0;

	/** The pulse. */
	@XmlElement
	int pulse = 0;

	/** The presence. */
	@XmlElement
	boolean presence = false;

	/** The speed. */
	@XmlElement
	double speed = 0.0;

	/** The length. */
	@XmlElement
	double length = 0.0;


	/** Gets the string representation. */
	@Override
	public String toString() {
		StringBuilder ret = new StringBuilder();

		ret.append("detectorId = ");
		ret.append(detectorId);
		ret.append("\n");
		ret.append("pulse = ");
		ret.append(pulse);
		ret.append("\n");
		ret.append("presence = ");
		ret.append(presence);
		ret.append("\n");
		ret.append("speed = ");
		ret.append(speed);
		ret.append("\n");
		ret.append("length = ");
		ret.append(length);

		return ret.toString();
	}
	
	/**
	 * Check if de is the same as this.
	 * @param object The DetectorEvent to test against.
	 * @return If the object are equal.
	 */
	@Override
	public boolean equals(Object object) {
		if(object instanceof DetectorEvent) {
			DetectorEvent de = (DetectorEvent) object;
			
			return detectorId == de.detectorId &&
					pulse == de.pulse &&
					presence == de.presence &&
					closeEnough(speed, de.speed) &&
					closeEnough(length, de.length);
		} else {
			return false;
		}
		
	}
	
	/**
	 * HashCode operation. 
	 * @return A hashcode of the data. 
	 */
	@Override
	public int hashCode() {
		return new HashCodeBuilder(55, 7).
				append(detectorId).
				append(pulse).
				append(presence).
				append(speed).
				append(length).
				toHashCode();
	}
	
	/**
	 * Simple check to see if d1 is close enough to d2 given floating point arithmatic.
	 * @param d1
	 * @param d2
	 * @return See if the 2 values are approximate.
	 */
	private boolean closeEnough(double d1, double d2) {
		return ((d1 - d2) <= 0.05) && ((d1 - d2) >= -0.05);
	}

	/**
	 * Gets the detector ID. 
	 * @return The detector ID.
	 */
	public int getDetectorId() {
		return detectorId;
	}

	/**
	 * Sets the detector ID.
	 * @param detectorId The detector ID.
	 */
	public void setDetectorId(int detectorId) {
		this.detectorId = detectorId;
	}

	/**
	 * Gets the pulse.
	 * @return The pulse.
	 */
	public int getPulse() {
		return pulse;
	}

	/**
	 * Sets the pulse.
	 * @param pulse The new pulse.
	 */
	public void setPulse(int pulse) {
		this.pulse = pulse;
	}

	/**
	 * Is presence?
	 * @return True/False
	 */
	public boolean isPresence() {
		return presence;
	}

	/**
	 * Sets the presence.
	 * @param presence True/False
	 */
	public void setPresence(boolean presence) {
		this.presence = presence;
	}

	/**
	 * Gets the speed.
	 * @return The speed.
	 */
	public double getSpeed() {
		return speed;
	}

	/**
	 * Sets the speed.
	 * @param speed The new speed.
	 */
	public void setSpeed(double speed) {
		this.speed = speed;
	}

	/**
	 * Gets the length.
	 * @return The length.
	 */
	public double getLength() {
		return length;
	}

	/**
	 * Sets the length.
	 * @param length The new length.
	 */
	public void setLength(double length) {
		this.length = length;
	}
}